﻿using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Z.BulkOperations;

namespace EntityFrameworkCoreUtils
{
    /// <summary>
    /// 基础仓储接口
    /// </summary>
    public partial interface IRepository<TEntity> where TEntity : class
    {
        #region 方法

        /// <summary>
        /// 查询对象
        /// </summary>
        /// <param name="OrderBy">排序String,Ps:id desc</param>
        /// <param name="predicate">Linq 条件</param>
        /// <returns></returns>
        TEntity GetOne(string OrderBy, Expression<Func<TEntity, bool>> predicate);
        /// <summary>
        /// 获取数量
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <returns></returns>
        int Count(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 获取数量
        /// </summary>
        /// <param name="ExpressionsSql">id=@0</param>
        /// <param name="ExpressionPartams">123</param>
        /// <returns></returns>
        int Count(string ExpressionsSql, params object[] ExpressionPartams);

        /// <summary>
        /// 获取数量
        /// </summary>
        /// <param name="ExpressionsSql">查询条件</param>
        /// <param name="ExpressionPartams">查询条件</param>
        /// <returns></returns>
        int Count(string ExpressionsSql);
        /// <summary>
        /// 判断数据是否存在
        /// </summary>
        /// <param name="predicate">判断条件</param>
        /// <returns></returns>
        bool IsExists(Expression<Func<TEntity, bool>> predicate);


        /// <summary>
        /// 获取数据列表
        /// </summary>
        /// <param name="OrderBy">排序字符串</param>
        /// <param name="expressions">条件集合</param>
        /// <returns></returns>
        List<TEntity> GetList(string OrderBy, List<Expression<Func<TEntity, bool>>> expressions);

        /// <summary>
        /// 查询列表根据Sql条件
        /// </summary>
        /// <param name="OrderBy"></param>
        /// <param name="ExpressionsSql">id=@0</param>
        /// <param name="ExpressionPartams">125</param>
        /// <returns></returns>
        List<TEntity> GetList(string OrderBy, string ExpressionsSql, params object[] ExpressionPartams);
        /// <summary>
        /// 查询列表根据Sql条件
        /// </summary>
        /// <param name="OrderBy"></param>
        /// <param name="ExpressionsSql">id=@0</param>
        /// <returns></returns>
        List<TEntity> GetList(string OrderBy, string ExpressionsSql);



        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="iPage"></param>
        /// <param name="PageSize"></param>
        /// <param name="OrderBy"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        PageOf<TEntity> GetPageList(int iPage, int PageSize, string OrderBy, List<Expression<Func<TEntity, bool>>> predicate);

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="iPage"></param>
        /// <param name="PageSize"></param>
        /// <param name="OrderBy"></param>
        /// <param name="ExpressionsSql"></param>
        /// <returns></returns>
        PageOf<TEntity> GetPageList(int iPage, int PageSize, string OrderBy, string ExpressionsSql);
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="iPage"></param>
        /// <param name="PageSize"></param>
        /// <param name="OrderBy"></param>
        /// <param name="ExpressionsSql"></param>
        /// <param name="ExpressionPartams"></param>
        /// <returns></returns>
        PageOf<TEntity> GetPageList(int iPage, int PageSize, string OrderBy, string ExpressionsSql, params object[] ExpressionPartams);

        #region 删除
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="predicate"></param>
        int Delete(Expression<Func<TEntity, bool>> predicate);


        /// <summary>
        /// 删除
        /// </summary>
        void Delete(TEntity entity);


        /// <summary>
        /// 批量删除
        /// </summary>
        void Delete(IEnumerable<TEntity> entities);
        #endregion



        #region 插入
        /// <summary>
        /// 添加
        /// </summary>
        TEntity Insert(TEntity entity);

        /// <summary>
        /// 批量添加
        /// </summary>
        void BulkInsert(IEnumerable<TEntity> entities);
        #endregion


        #region 修改
        /// <summary>
        /// 修改
        /// </summary>
        TEntity Update(TEntity entity);

        /// <summary>
        /// 批量修改
        /// </summary>
        void Update(IEnumerable<TEntity> entities);

        int Update(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TEntity>> updator);
        #endregion


        #region 数据合并/同步
        /// <summary>
        /// 合并（插入或更新/更新）数据库中的大量实体
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="options">
        ///   MergeKeepIdentity:
        ///     是否保留实体的标识值
        ///
        ///   ColumnPrimaryKeyExpression:
        ///     映射的属性
        ///
        ///   ColumnIgnoreExpression:
        ///     忽略自动映射的属性
        ///
        ///   IgnoreOnMergeInsertExpression:
        ///     合并时插入忽略的字段
        ///
        ///   IgnoreOnMergeUpdateExpression:
        ///     合并时修改忽略的字段
        /// </param>
        void BulkMerge(IEnumerable<TEntity> entities, Action<BulkOperation<TEntity>> options);


        /// <summary>
        ///同步数据库中的大量实体
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="options">
        ///   SynchronizeKeepIdentity:
        ///     是否保留实体的标识值
        ///
        ///   ColumnPrimaryKeyExpression:
        ///     映射的属性
        ///
        ///   ColumnInputExpression:
        ///     映射的属性
        ///
        ///   IgnoreOnSynchronizeInsertExpression:
        ///     同步时插入忽略的字段
        ///
        ///   IgnoreOnSynchronizeUpdateExpression:
        ///     同步时修改忽略的字段
        /// </param>
        void BulkSynchronize(IEnumerable<TEntity> entities, Action<BulkOperation<TEntity>> options);
        #endregion

        #endregion

        #region 属性
        /// <summary>
        /// 查询数据集
        /// </summary>
        IQueryable<TEntity> Table { get; }

        IQueryable<TOther> OtherTable<TOther>() where TOther : class;

        /// <summary>
        /// 获取一个启用“no tracking”(EF特性)的表，仅当您仅为只读操作加载记录时才使用它
        /// </summary>
        IQueryable<TEntity> TableNoTracking { get; }


        DbSet<TEntity> Entities { get; }

        #endregion
    }
}
